package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.pojo.Sortings;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.ying.space.core.dao.DesignerProjectDAO;
import com.ecoolex.ying.space.entity.DesignerProject;
import com.ecoolex.ying.space.entity.DesignerProject.Column;
import com.ecoolex.ying.space.entity.DesignerProjectExample;
import com.ecoolex.ying.space.enums.DesignerProjectType;
import com.ecoolex.ying.space.pojo.EditDesignerProjectDTO;
import com.ecoolex.ying.space.pojo.QueryDesignerProjectByUserDTO;
import com.ecoolex.ying.space.pojo.QueryDesignerProjectDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Date;
import java.time.Instant;

import static com.ecoolex.ying.space.entity.DesignerProject.*;

@Service
public class DesignerProjectManager {
    @Autowired
    private DesignerProjectDAO dao;

    @Autowired
    private DesignerProjectAttributeManager designerProjectAttributeManager;
    @Autowired
    private DesignerProjectShareManager designerProjectShareManager;
    @Autowired
    private DesignerProjectItemsManager designerProjectItemsManager;
    @Autowired
    private DesignerProjectItemsProductManager designerProjectItemsProductManager;
    @Autowired
    private DesignerProjectItemsProductCustomManager designerProjectItemsProductCustomManager;

    private void verify(EditDesignerProjectDTO record) {
        BizAssert.isTrue(Check.notNullOrTrimEmpty(record.getName()), ResultCode.VERIFY.build(10), "项目名称不能为空");
        BizAssert.isTrue(Check.notNull(DesignerProjectType.realValueOf(record.getType())), ResultCode.VERIFY.build(11), "项目类型不能为空");
    }

    public DesignerProject copy(Integer userId, DesignerProject project, String createUser) {
        Integer sourceProjectId = project.getProjectId();
        if (project.getName().indexOf(" (副本)") < 0) {
            project.setName(project.getName() + " (副本)");
        }
        project.setCreateUser(createUser);
        project.setCreateTime(Date.from(Instant.now()));
        project.setUpdateUser(createUser);
        project.setUpdateTime(Date.from(Instant.now()));
        dao.insert(project);

        // 删除属性
        designerProjectAttributeManager.copy(sourceProjectId, project, createUser);
        // 删除条目
        designerProjectItemsManager.copy(sourceProjectId, project, createUser);

        return project;
    }

    @Transactional
    public DesignerProject create(Integer userId, EditDesignerProjectDTO add, String createUser) {
        verify(add);

        DesignerProject record = new DesignerProject();
        record.setUserId(userId);
        record.setType(add.getType());
        record.setName(add.getName());
        record.setDescription(add.getDescription());
        record.setCoverImage(add.getCoverImage());
        record.setDeleted(NOT_DELETED);
        record.setCreateUser(createUser);
        record.setCreateTime(Date.from(Instant.now()));
        record.setUpdateUser(createUser);
        record.setUpdateTime(Date.from(Instant.now()));
        dao.insert(record);

        designerProjectAttributeManager.create(record, createUser);
        return record;
    }

    @Transactional
    public void update(Integer userId, Integer projectId, EditDesignerProjectDTO edit, String updateUser) {
        verify(edit);

        DesignerProject record = new DesignerProject();
        record.setName(edit.getName());
        record.setDescription(edit.getDescription());
        record.setCoverImage(edit.getCoverImage());
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        DesignerProjectExample example = new DesignerProjectExample();
        example.createCriteria()
                .andProjectIdEqualTo(projectId)
                .andUserIdEqualTo(userId)
                .andDeletedEqualTo(NOT_DELETED);

        int row = dao.updateByExampleSelective(record,
                example,
                Column.name,
                Column.description,
                Column.coverImage,
                Column.updateUser,
                Column.updateTime);
        BizAssert.isTrue(row == 1, ResultCode.BIZ.build(10), "修改设计师项目失败");
    }

    @Transactional
    public void delete(Integer userId, Integer projectId, String updateUser) {
        DesignerProject record = new DesignerProject();
        record.setDeleted(IS_DELETED);
        record.setUpdateUser(updateUser);
        record.setUpdateTime(Date.from(Instant.now()));

        DesignerProjectExample example = new DesignerProjectExample();
        example.createCriteria()
                .andProjectIdEqualTo(projectId)
                .andUserIdEqualTo(userId)
                .andDeletedEqualTo(NOT_DELETED);

        int row = dao.updateByExampleSelective(record,
                example,
                Column.deleted,
                Column.updateUser,
                Column.updateTime);
        BizAssert.isTrue(row == 1, ResultCode.BIZ.build(10), "删除设计师项目失败");

        // 删除属性
        designerProjectAttributeManager.delete(userId, projectId, updateUser);
        // 删除分享
        designerProjectShareManager.deleteByProjectId(projectId, updateUser);
        // 删除条目
        designerProjectItemsManager.deleteByProjectId(projectId, updateUser);
        // 删除关联的商品
        designerProjectItemsProductManager.deleteByProjectId(projectId, updateUser);
        // 删除商品自定义数据
        designerProjectItemsProductCustomManager.deleteByProjectId(projectId, updateUser);
    }

    public DesignerProject getByUserIdAndId(Integer userId, Integer projectId) {
        DesignerProjectExample example = new DesignerProjectExample();
        example.createCriteria()
                .andProjectIdEqualTo(projectId)
                .andUserIdEqualTo(userId)
                .andDeletedEqualTo(NOT_DELETED);
        return dao.selectOneByExample(example);
    }

    public Pagination<DesignerProject> queryByUserId(QueryDesignerProjectByUserDTO query, Integer userId, Sorting[] sorts, Page page) {
        DesignerProjectExample example = new DesignerProjectExample();
        DesignerProjectExample.Criteria criteria = example.createCriteria();

        if (Check.notNull(query.getType())) {
            criteria.andTypeEqualTo(query.getType());
        }
        if (Check.notNullOrTrimEmpty(query.getKeywork())) {
            String keywork = '%' + query.getKeywork() + '%';
            criteria.andNameLike(keywork);
        }
        criteria.andUserIdEqualTo(userId)
                .andDeletedEqualTo(NOT_DELETED);

        example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
        example.setOffset(page.getFirstIndex());
        example.setRows(page.getPageSize());

        return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExample(example));
    }

    public DesignerProject getById(Integer projectId) {
        DesignerProjectExample example = new DesignerProjectExample();
        example.createCriteria()
                .andProjectIdEqualTo(projectId)
                .andDeletedEqualTo(NOT_DELETED);
        return dao.selectOneByExample(example);
    }

    public Pagination<DesignerProject> query(QueryDesignerProjectDTO query, Sorting[] sorts, Page page) {

        DesignerProjectExample example = new DesignerProjectExample();
        DesignerProjectExample.Criteria criteria = example.createCriteria()
                .andDeletedEqualTo(NOT_DELETED);

        if (Check.notNull(query.getUserId())) {
            criteria.andUserIdEqualTo(query.getUserId());
        }

        example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
        example.setOffset(page.getFirstIndex());
        example.setRows(page.getPageSize());

        return Pagination.create(page, dao.countByExample(example), () -> dao.selectByExample(example));
    }


}